package com.caiheng.api.util;

import java.math.BigInteger;

/**
 * @author by  zhouwei
 * @createtime 2017/11/15 22:54
 * @功能：
 */
public class CRCUtil {

    public static void main(String[] args) {
        String str = "00C8FFFFE5DB000100000A008122D4C1423132333435362CCDA3B3B531D0A1CAB13330B7D62CC7EBBDBBB7D13130D4AA424DB2000000000000003E000000280000001D000000E3FFFFFF01000100000000000000000000000000000000000000000000000000FFFFFF0000000000FE4533F882858A08BA673AE8BA70FAE8BA660AE882DD2A08FEAAABF8009DF8000F02331055461CA88A7D0C60494741007BE49670BDA22D582E49317075F125F022A90EF08CE7110017B0D3A00438FCF0CA98AFF800DB68D0FE9C9AA082B628F8BA85EFC8BA6822E0BA4BD4D882085718FE421DB0";
        byte[] bytes = ByteUtil.hexStringToByteArray(str);
        String crc = CRCUtil.getCRC(bytes);
        System.out.println("crc: " + crc);
    }

    /**
     * 计算产生校验码
     * @param data 需要校验的数据
     * @return 校验码
     */
    public static String Make_CRC(byte[] data) {
        byte[] buf = new byte[data.length];// 存储需要产生校验码的数据
        for (int i = 0; i < data.length; i++) {
            buf[i] = data[i];
        }
        int len = buf.length;
        int crc = 0xFFFF;//16位
        for (int pos = 0; pos < len; pos++) {
            if (buf[pos] < 0) {
                crc ^= (int) buf[pos] + 256; // XOR byte into least sig. byte of
                // crc
            } else {
                crc ^= (int) buf[pos]; // XOR byte into least sig. byte of crc
            }
            for (int i = 8; i != 0; i--) { // Loop over each bit
                if ((crc & 0x0001) != 0) { // If the LSB is set
                    crc >>= 1; // Shift right and XOR 0xA001
                    crc ^= 0xA001;
                } else
                    // Else LSB is not set
                    crc >>= 1; // Just shift right
            }
        }
        String c = Integer.toHexString(crc);
        if (c.length() == 4) {
            c = c.substring(2, 4) + c.substring(0, 2);
        } else if (c.length() == 3) {
            c = "0" + c;
            c = c.substring(2, 4) + c.substring(0, 2);
        } else if (c.length() == 2) {
            c = "0" + c.substring(1, 2) + "0" + c.substring(0, 1);
        }
        return c;
    }


    /**
     *  计算CRC16校验码
     * @param data  高位在前  地位在后
     * @return
     */
    public static String getCrc(String data){
        byte[] bytes = ByteUtil.hexStringToByteArray(data);
        String crc = CRCUtil.getCRC(bytes);
        return crc;
    }

    /**
     * 计算CRC16校验码
     *
     * @param bytes 字节数组
     * @return {@link String} 校验码
     * @since 1.0
     */
    public static String getCRC(byte[] bytes) {
        int CRC = 0x0000ffff;
        int POLYNOMIAL = 0x0000a001;
        int i, j;
        for (i = 0; i < bytes.length; i++) {
            CRC ^= ((int) bytes[i] & 0x000000ff);
            for (j = 0; j < 8; j++) {
                if ((CRC & 0x00000001) != 0) {
                    CRC >>= 1;
                    CRC ^= POLYNOMIAL;
                } else {
                    CRC >>= 1;
                }
            }
        }
//        CRC = Integer.reverse(CRC);
        String ret = Integer.toHexString(CRC).toUpperCase();
        //高位在前地位在后
        ret = ret.substring(2, 4) + ret.substring(0, 2);
        return ret;
    }

    /**
     * 将16进制单精度浮点型转换为10进制浮点型
     *
     * @return float
     * @since 1.0
     */
    private float parseHex2Float(String hexStr) {
        BigInteger bigInteger = new BigInteger(hexStr, 16);
        return Float.intBitsToFloat(bigInteger.intValue());
    }

    /**
     * 将十进制浮点型转换为十六进制浮点型
     *
     * @return String
     * @since 1.0
     */
    private String parseFloat2Hex(float data) {
        return Integer.toHexString(Float.floatToIntBits(data));
    }
}
